<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>The source code</title>
  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  <style type="text/css">
    .highlight { display: block; background-color: #ddd; }
  </style>
  <script type="text/javascript">
    function highlight() {
      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
    }
  </script>
</head>
<body onload="prettyPrint(); highlight();">
  <pre class="prettyprint lang-js"><span id='BUI'>/**
</span> * @fileOverview 抽象数据缓冲类
 * @ignore
 */

  var BUI = require(&#39;bui-common&#39;),
    Proxy = require(&#39;./proxy&#39;);

<span id='BUI-Data-AbstractStore'>  /**
</span>   * @class BUI.Data.AbstractStore
   * 数据缓冲抽象类,此类不进行实例化
   * @extends BUI.Base
   */
  function AbstractStore(config){
    AbstractStore.superclass.constructor.call(this,config);
    this._init();
  }

  AbstractStore.ATTRS = {

<span id='BUI-Data-AbstractStore-cfg-autoLoad'>    /**
</span>    * 创建对象时是否自动加载
    * &lt;pre&gt;&lt;code&gt;
    *   var store = new Data.Store({
    *     url : &#39;data.php&#39;,  //设置加载数据的URL
    *     autoLoad : true    //创建Store时自动加载数据
    *   });
    * &lt;/code&gt;&lt;/pre&gt;
    * @cfg {Boolean} [autoLoad=false]
    */
    autoLoad: {
      value :false 
    },
<span id='BUI-Data-AbstractStore-property-remoteFilter'>    /**
</span>     * 是否服务器端过滤数据，如果设置此属性，当调用filter()函数时发送请求
     * @type {Object}
     */
    remoteFilter: {
        value : false
    },
<span id='BUI-Data-AbstractStore-property-lastParams'>    /**
</span>     * 上次查询的参数
     * @type {Object}
     * @readOnly
     */
    lastParams : {
      shared : false,
      value : {}
    },
<span id='BUI-Data-AbstractStore-cfg-params'>    /**
</span>     * 初始化时查询的参数，在初始化时有效
     * &lt;pre&gt;&lt;code&gt;
     * var store = new Data.Store({
    *     url : &#39;data.php&#39;,  //设置加载数据的URL
    *     autoLoad : true,    //创建Store时自动加载数据
    *     params : {         //设置请求时的参数
    *       id : &#39;1&#39;,
    *       type : &#39;1&#39;
    *     }
    *   });
     * &lt;/code&gt;&lt;/pre&gt;
     * @cfg {Object} params
     */
    params : {

    },
<span id='BUI-Data-AbstractStore-cfg-errorProperty'>    /**
</span>     * 错误字段,包含在返回信息中表示错误信息的字段
     * &lt;pre&gt;&lt;code&gt;
     *   //可以修改接收的后台参数的含义
     *   var store = new Store({
     *     url : &#39;data.json&#39;,
     *     errorProperty : &#39;errorMsg&#39;, //存放错误信息的字段(error)
     *     hasErrorProperty : &#39;isError&#39;, //是否错误的字段（hasError)
     *     root : &#39;data&#39;,               //存放数据的字段名(rows)
     *     totalProperty : &#39;total&#39;     //存放记录总数的字段名(results)
     *   });
     * &lt;/code&gt;&lt;/pre&gt;
     * @cfg {String} [errorProperty=&#39;error&#39;]
     */
<span id='global-property-errorProperty'>    /**
</span>     * 错误字段
     * @type {String}
     * @ignore
     */
    errorProperty : {
      value : &#39;error&#39;
    },
<span id='BUI-Data-AbstractStore-cfg-hasErrorProperty'>    /**
</span>     * 是否存在错误,加载数据时如果返回错误，此字段表示有错误发生
     * &lt;pre&gt;&lt;code&gt;
     *   //可以修改接收的后台参数的含义
     *   var store = new Store({
     *     url : &#39;data.json&#39;,
     *     errorProperty : &#39;errorMsg&#39;, //存放错误信息的字段(error)
     *     hasErrorProperty : &#39;isError&#39;, //是否错误的字段（hasError)
     *     root : &#39;data&#39;,               //存放数据的字段名(rows)
     *     totalProperty : &#39;total&#39;     //存放记录总数的字段名(results)
     *   });
     * &lt;/code&gt;&lt;/pre&gt;
     * @cfg {String} [hasErrorProperty=&#39;hasError&#39;]
     */
<span id='global-property-hasErrorProperty'>    /**
</span>     * 是否存在错误
     * @type {String}
     * @default &#39;hasError&#39;
     * @ignore
     */
    hasErrorProperty : {
      value : &#39;hasError&#39;
    },
<span id='BUI-Data-AbstractStore-cfg-proxy'>    /**
</span>     * 数据代理对象,用于加载数据的ajax配置，{@link BUI.Data.Proxy}
     * &lt;pre&gt;&lt;code&gt;
     *   var store = new Data.Store({
    *     url : &#39;data.php&#39;,  //设置加载数据的URL
    *     autoLoad : true,    //创建Store时自动加载数据
    *     proxy : {
    *       method : &#39;post&#39;,
    *       dataType : &#39;jsonp&#39;
    *     }
    *   });
     * &lt;/code&gt;&lt;/pre&gt;
     * @cfg {Object|BUI.Data.Proxy} proxy
     */
    proxy : {
      shared : false,
      value : {
        
      }
    },
<span id='BUI-Data-AbstractStore-cfg-url'>    /**
</span>     * 请求数据的地址，通过ajax加载数据，
     * 此参数设置则加载远程数据
     * ** 你可以设置在proxy外部 **
     * &lt;pre&gt;&lt;code&gt;
     *   var store = new Data.Store({
    *     url : &#39;data.php&#39;,  //设置加载数据的URL
    *     autoLoad : true,    //创建Store时自动加载数据
    *     proxy : {
    *       method : &#39;post&#39;,
    *       dataType : &#39;jsonp&#39;
    *     }
    *   });
     * &lt;/code&gt;&lt;/pre&gt;
     * ** 你也可以设置在proxy上 **
     * &lt;pre&gt;&lt;code&gt;
     *   var store = new Data.Store({
    *     autoLoad : true,    //创建Store时自动加载数据
    *     proxy : {
    *       url : &#39;data.php&#39;,  //设置加载数据的URL
    *       method : &#39;post&#39;,
    *       dataType : &#39;jsonp&#39;
    *     }
    *   });
     * &lt;/code&gt;&lt;/pre&gt;
     * 否则把 {BUI.Data.Store#cfg-data}作为本地缓存数据加载
     * @cfg {String} url
     */
<span id='BUI-Data-AbstractStore-property-url'>    /**
</span>     * 请求数据的url
     * &lt;pre&gt;&lt;code&gt;
     *   //更改url
     *   store.get(&#39;proxy&#39;).set(&#39;url&#39;,url);
     * &lt;/code&gt;&lt;/pre&gt;
     * @type {String}
     */
    url : {

    },
    events : {
      value : [
<span id='BUI-Data-AbstractStore-event-acceptchanges'>        /**  
</span>        * 数据接受改变，所有增加、删除、修改的数据记录清空
        * @name BUI.Data.Store#acceptchanges
        * @event  
        */
        &#39;acceptchanges&#39;,
<span id='BUI-Data-AbstractStore-event-load'>        /**  
</span>        * 当数据加载完成后
        * @name BUI.Data.Store#load  
        * @event  
        * @param {jQuery.Event} e  事件对象，包含加载数据时的参数
        */
        &#39;load&#39;,

<span id='BUI-Data-AbstractStore-event-beforeload'>        /**  
</span>        * 当数据加载前
        * @name BUI.Data.Store#beforeload
        * @event  
        */
        &#39;beforeload&#39;,

<span id='BUI-Data-AbstractStore-event-beforeprocessload'>        /**  
</span>        * 发生在，beforeload和load中间，数据已经获取完成，但是还未触发load事件，用于获取返回的原始数据
        * @event  
        * @param {jQuery.Event} e  事件对象
        * @param {Object} e.data 从服务器端返回的数据
        */
        &#39;beforeprocessload&#39;,
        
<span id='BUI-Data-AbstractStore-event-add'>        /**  
</span>        * 当添加数据时触发该事件
        * @event  
        * @param {jQuery.Event} e  事件对象
        * @param {Object} e.record 添加的数据
        */
        &#39;add&#39;,

<span id='BUI-Data-AbstractStore-event-exception'>        /**
</span>        * 加载数据发生异常时触发
        * @event
        * @name BUI.Data.Store#exception
        * @param {jQuery.Event} e 事件对象
        * @param {String|Object} e.error 加载数据时返回的错误信息或者加载数据失败，浏览器返回的信息（httpResponse 对象 的textStatus）
        * @param {String} e.responseText 网络或者浏览器加载数据发生错误是返回的httpResponse 对象的responseText
        */
        &#39;exception&#39;,

<span id='BUI-Data-AbstractStore-event-remove'>        /**  
</span>        * 当删除数据是触发该事件
        * @event  
        * @param {jQuery.Event} e  事件对象
        * @param {Object} e.data 删除的数据
        */
        &#39;remove&#39;,
        
<span id='BUI-Data-AbstractStore-event-update'>        /**  
</span>        * 当更新数据指定字段时触发该事件 
        * @event  
        * @param {jQuery.Event} e  事件对象
        * @param {Object} e.record 更新的数据
        * @param {Object} e.field 更新的字段
        * @param {Object} e.value 更新的值
        */
        &#39;update&#39;,

<span id='BUI-Data-AbstractStore-event-localsort'>        /**  
</span>        * 前端发生排序时触发
        * @name BUI.Data.Store#localsort
        * @event  
        * @param {jQuery.Event} e  事件对象
        * @param {Object} e.field 排序的字段
        * @param {Object} e.direction 排序的方向 &#39;ASC&#39;，&#39;DESC&#39;
        */
        &#39;localsort&#39;,

<span id='BUI-Data-AbstractStore-event-filtered'>        /**  
</span>        * 前端发生过滤时触发
        * @event  
        * @param {jQuery.Event} e  事件对象
        * @param {Array} e.data 过滤完成的数据
        * @param {Function} e.filter 过滤器
        */
        &#39;filtered&#39;
      ]
    },
<span id='BUI-Data-AbstractStore-cfg-data'>    /**
</span>     * 本地数据源,使用本地数据源时会使用{@link BUI.Data.Proxy.Memery}
     * @cfg {Array} data
     */
<span id='BUI-Data-AbstractStore-property-data'>    /**
</span>     * 本地数据源
     * @type {Array}
     */
    data : {
      setter : function(data){
        var _self = this,
          proxy = _self.get(&#39;proxy&#39;);
        if(proxy.set){
          proxy.set(&#39;data&#39;,data);
        }else{
          proxy.data = data;
        }
        //设置本地数据时，把autoLoad置为true
        _self.set(&#39;autoLoad&#39;,true);
      }
    }
  };

  BUI.extend(AbstractStore,BUI.Base);

  BUI.augment(AbstractStore,{
<span id='BUI-Data-AbstractStore-property-isStore'>    /**
</span>     * 是否是数据缓冲对象，用于判断对象
     * @type {Boolean}
     */
    isStore : true,
<span id='BUI-Data-AbstractStore-method-_init'>    /**
</span>     * @private
     * 初始化
     */
    _init : function(){
      var _self = this;

      _self.beforeInit();
      //初始化结果集
      _self._initParams();
      _self._initProxy();
      _self._initData();
    },
<span id='BUI-Data-AbstractStore-method-beforeInit'>    /**
</span>     * @protected
     * 初始化之前
     */
    beforeInit : function(){

    },
    //初始化数据,如果默认加载数据，则加载数据
    _initData : function(){
      var _self = this,
        autoLoad = _self.get(&#39;autoLoad&#39;);

      if(autoLoad){
        _self.load();
      }
    },
    //初始化查询参数
    _initParams : function(){
      var _self = this,
        lastParams = _self.get(&#39;lastParams&#39;),
        params = _self.get(&#39;params&#39;);

      //初始化 参数
      BUI.mix(lastParams,params);
    },
<span id='BUI-Data-AbstractStore-method-_initProxy'>    /**
</span>     * @protected
     * 初始化数据代理类
     */
    _initProxy : function(){
      var _self = this,
        url = _self.get(&#39;url&#39;),
        proxy = _self.get(&#39;proxy&#39;);

      if(!(proxy instanceof Proxy)){

        if(url){
          proxy.url = url;
        }

        //异步请求的代理类
        if(proxy.type === &#39;ajax&#39; || proxy.url){
          proxy = new Proxy.Ajax(proxy);
        }else{
          proxy = new Proxy.Memery(proxy);
        }

        _self.set(&#39;proxy&#39;,proxy);
      }
    },
<span id='BUI-Data-AbstractStore-method-load'>    /**
</span>     * 加载数据
     * &lt;pre&gt;&lt;code&gt;
     *  //一般调用
     *  store.load(params);
     *  
     *  //使用回调函数
     *  store.load(params,function(data){
     *  
     *  });
     *
     *  //load有记忆参数的功能
     *  store.load({id : &#39;123&#39;,type=&quot;1&quot;});
     *  //下一次调用
     *  store.load();默认使用上次的参数，可以对对应的参数进行覆盖
     * &lt;/code&gt;&lt;/pre&gt;
     * @param  {Object} params 参数键值对
     * @param {Function} fn 回调函数，默认为空
     */
    load : function(params,callback){
      var _self = this,
        proxy = _self.get(&#39;proxy&#39;),
        lastParams = _self.get(&#39;lastParams&#39;);

      BUI.mix(lastParams,_self.getAppendParams(),params);

      _self.fire(&#39;beforeload&#39;,{params:lastParams});

      //防止异步请求未结束，又发送新请求回调参数错误
      params = BUI.cloneObject(lastParams);
      proxy.read(lastParams,function(data){
        _self.onLoad(data,params);
        if(callback){
          callback(data,params);
        }
      },_self);
    },
<span id='BUI-Data-AbstractStore-method-onFiltered'>    /**
</span>     * 触发过滤
     * @protected
     */
    onFiltered : function(data,filter){
      var _self = this;
      _self.fire(&#39;filtered&#39;,{data : data,filter : filter});
    },
<span id='BUI-Data-AbstractStore-method-onLoad'>    /**
</span>     * 加载完数据
     * @protected
     * @template
     */
    onLoad : function(data,params){
      var _self = this;

      var processResult = _self.processLoad(data,params);
      //如果处理成功，返回错误时，不进行后面的处理
      if(processResult){
        _self.afterProcessLoad(data,params);
      }
    },
<span id='BUI-Data-AbstractStore-method-getResult'>    /**
</span>     * 获取当前缓存的纪录
     */
    getResult : function(){
    },
<span id='BUI-Data-AbstractStore-method-filter'>    /**
</span>     * 过滤数据，此函数的执行同属性 remoteFilter关联密切
     *
     *  - remoteFilter == true时：此函数只接受字符串类型的过滤参数，将{filter : filterStr}参数传输到服务器端
     *  - remoteFilter == false时：此函数接受比对函数，只有当函数返回true时生效
     *  
     * @param {Function|String} fn 过滤函数
     * @return {Array} 过滤结果
     */
    filter : function(filter){
        var _self = this,
            remoteFilter = _self.get(&#39;remoteFilter&#39;),
            result;

        filter = filter || _self.get(&#39;filter&#39;);

        if(remoteFilter){
            _self.load({filter : filter});
        }else if(filter){
            _self.set(&#39;filter&#39;,filter);
            //如果result有值时才会进行filter
            if(_self.getResult().length &gt; 0){
                result = _self._filterLocal(filter);
                _self.onFiltered(result,filter);
            }
        }
    },
<span id='BUI-Data-AbstractStore-method-_filterLocal'>    /**
</span>     * @protected
     * 过滤缓存的数据
     * @param  {Function} fn 过滤函数
     * @return {Array} 过滤结果
     */
    _filterLocal : function(fn){
        
    },
<span id='BUI-Data-AbstractStore-method-getFilterResult'>    /**
</span>     * 获取过滤后的数据，仅当本地过滤(remoteFilter = false)时有效
     * @return {Array} 过滤过的数据
     */
    getFilterResult: function(){
        var filter = this.get(&#39;filter&#39;);
        if(filter) {
            return this._filterLocal(filter);
        }
        else {
            return this.getResult();
        }
    },
    _clearLocalFilter : function(){
        this.set(&#39;filter&#39;, null);
    },
<span id='BUI-Data-AbstractStore-method-clearFilter'>    /**
</span>     * 清理过滤
     */
    clearFilter : function(){
        var _self = this,
            remoteFilter = _self.get(&#39;remoteFilter&#39;),
            result;

        if(remoteFilter){
            _self.load({filter : &#39;&#39;});
        }else{
            _self._clearLocalFilter();
            result = _self.getFilterResult();
            _self.onFiltered(result, null);
        }
    },
<span id='BUI-Data-AbstractStore-method-processLoad'>    /**
</span>     * @private
     * 加载完数据处理数据
     */
    processLoad : function(data,params){
      var _self = this,
        hasErrorField = _self.get(&#39;hasErrorProperty&#39;);

      _self.fire(&#39;beforeprocessload&#39;,{data : data});
    
      //获取的原始数据
      _self.fire(&#39;beforeProcessLoad&#39;,data);

      if(BUI.getValue(data,hasErrorField) || data.exception){
        _self.onException(data);
        return false;
      }
      return true;
    },
<span id='BUI-Data-AbstractStore-method-afterProcessLoad'>    /**
</span>     * @protected
     * @template
     * 处理数据后
     */
    afterProcessLoad : function(data,params){

    },
<span id='BUI-Data-AbstractStore-method-onException'>    /**
</span>     * @protected
     * 处理错误函数
     * @param  {*} data 出错对象
     */
    onException : function(data){
      var _self = this,
        errorProperty = _self.get(&#39;errorProperty&#39;),
        obj = {};
      //网络异常、转码错误之类，发生在json获取或转变时
      if(data.exception){
        obj.type = &#39;exception&#39;;
        obj.error = data.exception;
      }else{//用户定义的错误
        obj.type = &#39;error&#39;;
        obj.error = BUI.getValue(data,errorProperty);
      }
      _self.fire(&#39;exception&#39;,obj);

    },
<span id='BUI-Data-AbstractStore-method-hasData'>    /**
</span>     * 是否包含数据
     * @return {Boolean} 
     */
    hasData : function(){

    },
<span id='BUI-Data-AbstractStore-method-getAppendParams'>    /**
</span>     * 获取附加的参数
     * @template
     * @protected
     * @return {Object} 附加的参数
     */
    getAppendParams : function(){
      return {};
    }
  });

module.exports = AbstractStore;
</pre>
</body>
</html>
